package crazyFace.system.app;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
 
public class GameView extends SurfaceView{	
	public static String saveFolder;
	private Bitmap playerbmp = BitmapFactory.decodeResource(getResources(), R.drawable.player);
	private Bitmap grass = BitmapFactory.decodeResource(getResources(), R.drawable.grassrepeate);
	private Bitmap coinbmp = BitmapFactory.decodeResource(getResources(), R.drawable.coin);
	private Bitmap skeliBMP = BitmapFactory.decodeResource(getResources(), R.drawable.skeli);
	private Bitmap spiderBMP = BitmapFactory.decodeResource(getResources(), R.drawable.spider);
	private Bitmap bomberBMP = BitmapFactory.decodeResource(getResources(), R.drawable.bomber);
	private Bitmap raperBMP = BitmapFactory.decodeResource(getResources(), R.drawable.raper);
	private Bitmap multifyerBMP = BitmapFactory.decodeResource(getResources(), R.drawable.multifyers);
	private Bitmap boss1BMP = BitmapFactory.decodeResource(getResources(), R.drawable.boss1);
	private Bitmap boss2BMP = BitmapFactory.decodeResource(getResources(), R.drawable.boss2);
	private Bitmap boss3BMP = BitmapFactory.decodeResource(getResources(), R.drawable.boss3);
	private Bitmap boss4BMP = BitmapFactory.decodeResource(getResources(), R.drawable.boss4);
	private Bitmap boss5BMP = BitmapFactory.decodeResource(getResources(), R.drawable.boss5);
	private Bitmap finalBossBMP = BitmapFactory.decodeResource(getResources(), R.drawable.raper);
	private Bitmap fireBMP = BitmapFactory.decodeResource(getResources(), R.drawable.fire);
	private Bitmap pistolBMP = BitmapFactory.decodeResource(getResources(), R.drawable.pistol_gui);
	private Bitmap pauseBMP = BitmapFactory.decodeResource(getResources(), R.drawable.pause);
	private Bitmap rifleBMP = BitmapFactory.decodeResource(getResources(), R.drawable.rifle_gui);
	private Bitmap tntBMP = BitmapFactory.decodeResource(getResources(), R.drawable.tnt_gui);
    private SurfaceHolder holder;
    private GameLoopThread gameLoopThread;
    private Random random = new Random();
    private Paint healthPaint = new Paint();
    private Paint textPaint = new Paint();
    private Paint highscorePaint = new Paint();
    private List<SharedPreferences> bundle = new ArrayList<SharedPreferences>();
       
    private static List<Button> GUI = new ArrayList<Button>();
    public static List<Player> playerHolder = new ArrayList<Player>();
    public static List<Coin> coins = new ArrayList<Coin>();
    public static List<Bullet> bullets = new ArrayList<Bullet>();
    public static List<Entity> enameys = new ArrayList<Entity>();
    public static List<Entity> items = new ArrayList<Entity>();
    public static List<Button> pauseGUITemp = new ArrayList<Button>();
    public static List<Integer> pauseMenu = new ArrayList<Integer>();
       
    public static boolean displayScores = false;
    public static boolean isPressed = false;
    public static boolean isPressed2 = false;
    public static boolean buttonPressed = false;
    public static boolean buttonPressed2 = false;
    public static int shootPressed = 0;
    public static boolean move = false;
    public static int minutes = 0;
    public static int seconds = 0;
    public static long beginTime = 0;
    public static boolean isbossDead = false;
    public static boolean bossBattle = false;
    public static long lastTouchFrame = 0;
    public static long lastPistolShoot = 0;
    public static long lastRifleShoot = 0;
    public static long lastTNTShoot = 0;
    public static int gunMode = 0;
    public static float xScroll = 0;
    public static float yScroll = 0;
    public static float xTouch = 0;
    public static float yTouch = 0;
    public static int width;
    public static int height;
    public static int xBound = 1500;
    public static int yBound = 1000;
    public static boolean crazy = false;
    public static boolean hasRifle = false;
    public static boolean hasTNT = false;
    public static boolean loading = false;
    public static long loadtime = 0;
    public static boolean loaded = false;
       
    public static boolean playing = false;
    public static int gameDif = 1;
    public static boolean hardcore = false;
    public static int score = 0;
    public static int monstersSpawned = 0;
    
    private SavingSystem saver = new SavingSystem(this);
 
    public GameView(Context context, SharedPreferences save, int width, int height, String saveFolder) {
    	super(context);
    	GameView.saveFolder = saveFolder;
    	healthPaint.setColor(Color.RED);
    	textPaint.setColor(Color.BLACK);
    	textPaint.setTextSize(18);
    	highscorePaint.setColor(Color.BLACK);
    	highscorePaint.setTextSize(32);
        GameView.width = width;
        GameView.height = height;
        bundle.add(save);
        gameLoopThread = new GameLoopThread(this);
        holder = getHolder();
        holder.addCallback(new Callback() {
 
        	public void surfaceDestroyed(SurfaceHolder holder) {
        	}
 
        	public void surfaceCreated(SurfaceHolder holder) {
        		mainMenu();
        		gameLoopThread.setRunning(true);
        		gameLoopThread.start();
        	}
 
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            }
        });
 
    }
       
	public void mainMenu(){
   	   	GUI.clear();
   	   	
   	   	GUI.add(createButton(createBMP(R.drawable.play_button), (int) (width * .25), (int) (height * .25)));
   	   	GUI.get(0).setAction(17);
   	   	
   	   	GUI.add(createButton(createBMP(R.drawable.how_button), (int) (width * .75), (int) (height * .25)));
   	   	GUI.get(1).setAction(2);
   	   
   	   	GUI.add(createButton(createBMP(R.drawable.scores_button), (int) (width * .25), (int) (height * .75)));
   	   	GUI.get(2).setAction(3);
   	   	
   	   	GUI.add(createButton(createBMP(R.drawable.about_button), (int) (width * .75), (int) (height * .75)));
   	   	GUI.get(3).setAction(9);
   	   	
   	   	playing = false;
	   	displayScores = false;
	   	xScroll = 0;
	   	yScroll = 0;
	}
	
	public void neworload(){
		GUI.clear();
		
		GUI.add(createButton(createBMP(R.drawable.new_button), (int) (width * .25), (int) (height * .5), 1));
		
		GUI.add(createButton(createBMP(R.drawable.load_button), (int) (width * .75), (int) (height * .5), 18));
	}
       
	public void gameSelect(){
		GUI.clear();
   	   
   	   	GUI.add(createButton(createBMP(R.drawable.easy_button), (int) (width * .25), (int) (height * .25)));
   	   	GUI.get(0).setAction(4);
   	   	
   	   	GUI.add(createButton(createBMP(R.drawable.normal_button), (int) (width * .75), (int) (height * .25)));
   	   	GUI.get(1).setAction(5);
   	   
   	   	GUI.add(createButton(createBMP(R.drawable.hard_button), (int) (width * .25), (int) (height * .75)));
   	   	GUI.get(2).setAction(6);
   	   	
   	   	GUI.add(createButton(createBMP(R.drawable.harder_button), (int) (width * .75), (int) (height * .75)));
   	   	GUI.get(3).setAction(7);
	}
      
	public void howToMenu(){
		GUI.clear();
   	   	
   	   	GUI.add(createButton(createBMP(R.drawable.how), (int) (width * .5), (int) (height * .5)));
   	   	
   	   	GUI.add(createButton(createBMP(R.drawable.back_button), (width - 110), (height - 55), 0));
   	   	
   	   	
	}
       
	public void scores(){
		GUI.clear();
  	   	
   	   	GUI.add(createButton(createBMP(R.drawable.back_button), (width - 110), (height - 55), 0));
   	   	
   	   	displayScores = true;
   	   
	}
      
	public void credits(){
		GUI.clear();
    	   
    	GUI.add(createButton(createBMP(R.drawable.speel), (int) (width * .5), (int) (height * .5)));
    	   
    	GUI.add(createButton(createBMP(R.drawable.back_button), (width - 110), (height - 55), 0));
    	   
       }
       
	public void pause(){
		int temp = 0;
    	   
		for(Button button : GUI){
			pauseGUITemp.add(button);
    	}
    	GUI.clear();
    	  
    	playing = false;
    	  
    	GUI .add(createButton(createBMP(R.drawable.resume_button), (int) (width * .5), (int) (height * .25), 16));
   	    temp = GUI.size() - 1;
   	    pauseMenu.add(temp);
   	   
   	    GUI .add(createButton(createBMP(R.drawable.exit_button), (int) (width * .5), (int) (height * .75), 0));
   	    temp = GUI.size() - 1;
   	    pauseMenu.add(temp);
   	    
   	    GUI .add(createButton(createBMP(R.drawable.save_button), (int) (width * .5), (int) (height * .5), 19));
	    temp = GUI.size() - 1;
	    pauseMenu.add(temp);
	}
       
	public void unpause(){
		playing = true;
    	GUI.clear();
    	for(Button button : pauseGUITemp){
    		GUI.add(button);
    	}
    	pauseGUITemp.clear();
    	pauseMenu.clear();
	}
       
       
    public void end(){
    	playing = false;
    	playerHolder.clear();
    	items.clear();
    	coins.clear();
    	bullets.clear();
    	enameys.clear();
    	 
    	monstersSpawned = 0;
    	   
    	SharedPreferences.Editor edit = bundle.get(0).edit();
    	
    	if(hardcore){
    		if(score > bundle.get(0).getInt("hardcore_highscore", 0)){
    			edit.putInt("hardcore_highscore", score);
    		}
    	}else if(gameDif == 1){
    		if(score > bundle.get(0).getInt("easy_highscore", 0)){
    			edit.putInt("easy_highscore", score);
    		}
    	}else if(gameDif == 2){
    		if(score > bundle.get(0).getInt("normal_highscore", 0)){
    			edit.putInt("normal_highscore", score);
    		}
    	}else if(gameDif == 3){
    		if(score > bundle.get(0).getInt("hard_highscore", 0)){
    			edit.putInt("hard_highscore", score);
    		}
    	}
    	score = 0;
    	   
    	edit.commit();
    	
    	mainMenu();
    }
 
    private void game() {
    	GUI.clear();
    	
    	GUI.add(createButton(fireBMP, (fireBMP.getWidth() / 2) - 2, height - 35));
    	GUI.get(0).setAction(8);
    	GUI.add(createButton(pistolBMP, (fireBMP.getWidth() / 2) + pistolBMP.getWidth(), height - 35));
    	GUI.get(1).setAction(11);
    	GUI.add(createButton(pauseBMP,  width - (pauseBMP.getWidth() / 2), (pauseBMP.getHeight() / 2)));
    	GUI.get(2).setAction(10);
    	
    	playerHolder.clear();
    	items.clear();
    	coins.clear();
    	bullets.clear();
    	enameys.clear();
    	   
    	displayScores = false;
        isPressed = false;
        buttonPressed = false;
        buttonPressed2 = false;
        shootPressed = 0;
        beginTime = System.currentTimeMillis();
        isbossDead = false;
        bossBattle = false;
        lastTouchFrame = 0;
        lastPistolShoot = 0;
        lastRifleShoot = 0;
        lastTNTShoot = 0;
        gunMode = 0;
        xScroll = 0;
        yScroll = 0;
        crazy = false;
        score = 0;
    	monstersSpawned = 0;
    	hasRifle = false;
    	hasTNT = false;
    	   
    	 
    	Player player = new Player(this, playerbmp);
    	playerHolder.add(player);
    	playing = true;
    	 
    	createCoins();
    }
    
    private void resumeGame() {
    	GUI.clear();
    	
    	GUI.add(createButton(fireBMP, (fireBMP.getWidth() / 2) - 2, height - 35));
    	GUI.get(0).setAction(8);
    	GUI.add(createButton(pistolBMP, (fireBMP.getWidth() / 2) + pistolBMP.getWidth(), height - 35));
    	GUI.get(1).setAction(11);
    	GUI.add(createButton(pauseBMP,  width - (pauseBMP.getWidth() / 2), (pauseBMP.getHeight() / 2)));
    	GUI.get(2).setAction(10);
    	
    	playerHolder.clear();
    	items.clear();
    	coins.clear();
    	bullets.clear();
    	enameys.clear();
    	   
    	displayScores = false;
        isPressed = false;
        buttonPressed = false;
        buttonPressed2 = false;
        shootPressed = 0;
        beginTime = System.currentTimeMillis();
        isbossDead = false;
        bossBattle = false;
        lastTouchFrame = 0;
        lastPistolShoot = 0;
        lastRifleShoot = 0;
        lastTNTShoot = 0;
        gunMode = 0;
        xScroll = 0;
        yScroll = 0;
        crazy = false;
        score = 0;
    	monstersSpawned = 0;
    	hasRifle = false;
    	hasTNT = false;
    	   
    	 
    	Player player = new Player(this, playerbmp);
    	playerHolder.add(player);
    	
    	saver.load();
    }
       
       
    public void createCoins(){
    	for(int i = 0; i < 500; i++){
    		Coin coin = new Coin(this, coinbmp);
    		coins.add(coin);
    	}
    } 
       
    public void createCoin(){
    	Coin coin = new Coin(this, coinbmp);
    	coins.add(coin);
    }
    public void createCoin(int x, int y){
    	Coin coin = new Coin(this, coinbmp, x, y);
    	coins.add(coin);
    }
       
    private Bitmap createBMP(int resouce) {
    	return BitmapFactory.decodeResource(getResources(), resouce);
    }
       
    public void createHeal(){
    	Heal heal = new Heal(this, createBMP(R.drawable.health), random.nextInt(xBound - 50), random.nextInt(yBound - 50));
    	items.add(heal);
    }
    public void createHeal(int x, int y){
    	Heal heal = new Heal(this, createBMP(R.drawable.health), x, y);
    	items.add(heal);
    }
       
    public void createBullet(){
    	Ammo bullet = new Ammo(this, createBMP(R.drawable.round), random.nextInt(xBound - 50), random.nextInt(yBound - 50));
    	items.add(bullet);
    }
    public void createBullets(int bullets){
    	for(int i = 0; i < bullets; i++){
    		createBullet();
    	}
    }
    public void createExplosion(int x, int y){
    	Explosion explosion = new Explosion(this, createBMP(R.drawable.explosion), 1, 10, x, y);
    	items.add(explosion);
    }
       
    private void shootBullet(int resouce, int x, int y) {
    	Bitmap bmp = BitmapFactory.decodeResource(getResources(), resouce);
    	Bullet bullet = new Bullet(this, bmp, playerHolder.get(0).aniRow, (int) playerHolder.get(0).getCenterX(), (int) playerHolder.get(0).getCenterY());
    	bullets.add(bullet);
    }
    public void createBullet(int direction, int x, int y) {
    	Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.bullet);
    	Bullet bullet = new Bullet(this, bmp, direction, x, y);
    	bullets.add(bullet);
    }
    
    /**
     * 0 = main menu;
     * 1 = game select;
     * 2 = how to menu;
     * 3 = scores menu;
     * 4 = play easy;
     * 5 = play normal;
     * 6 = play hard;
     * 7 = play hard core;
     * 8 = shoot;
     * 9 = credits;
     * 10 = pause;
     * 11 = pistol;
     * 12 = rifle;
     * 13 = tnt;
     * 14 = add rifle;
     * 15 = add tnt;
     * 16 = unpause;
     * 17 = load menu;
     * 18 = load;
     * 19 = save;
     * 20 = finish load;
     */
    public void action(int instruction){
    	
    	if(instruction == 0){
    		mainMenu();
    	}
    	if(instruction == 1){
    		gameSelect();
    	}
    	if(instruction == 2){
    		howToMenu();
    	}
    	if(instruction == 3){
    		scores();
    	}
    	if(instruction == 4){
    		gameDif = 1;
    		hardcore = false;
    		game();
    	}
    	if(instruction == 5){
    		gameDif = 2;
    		hardcore = false;
    		game();
    	}
    	if(instruction == 6){
    		gameDif = 3;
    		hardcore = false;
    		game();
    	}	
    	if(instruction == 7){
    		gameDif = 3;
    		hardcore = true;
    		game();
    	}
    	if(instruction == 8){
    		if(hardcore && playerHolder.get(0).ammo > 0){
    			if(gunMode == 0 && System.currentTimeMillis() - lastPistolShoot >= 1000){
    				shootBullet(R.drawable.bullet, (int) playerHolder.get(0).getCenterX(), (int) playerHolder.get(0).getCenterY());
    				shootBullet(R.drawable.bullet, (int) playerHolder.get(0).getCenterX(), (int) playerHolder.get(0).getCenterY());
    				playerHolder.get(0).ammo--;
    				lastPistolShoot = System.currentTimeMillis();
    			}if(gunMode == 2 && System.currentTimeMillis() - lastTNTShoot >= 30000 && playerHolder.get(0).ammo > 14){
    				createExplosion((int) playerHolder.get(0).x, (int) playerHolder.get(0).y);
    				playerHolder.get(0).ammo -= 15;
    				lastTNTShoot = System.currentTimeMillis();
    			}
    		}else if(!hardcore){
    			if(gunMode == 0 && System.currentTimeMillis() - lastPistolShoot >= 1000){
    				shootBullet(R.drawable.bullet, (int) playerHolder.get(0).getCenterX(), (int) playerHolder.get(0).getCenterY());
    				shootBullet(R.drawable.bullet, (int) playerHolder.get(0).getCenterX(), (int) playerHolder.get(0).getCenterY());
    				playerHolder.get(0).ammo--;
    				lastPistolShoot = System.currentTimeMillis();
    			}if(gunMode == 2 && System.currentTimeMillis() - lastTNTShoot >= 30000){
    				createExplosion((int) playerHolder.get(0).x, (int) playerHolder.get(0).y);
    				playerHolder.get(0).ammo -= 15;
    				lastTNTShoot = System.currentTimeMillis();
    			}
    		}
    	}
    	if(instruction == 9){
    		credits();/*BITCH TITS*/
    	}
    	if(instruction == 10){
    		pause();
    	}
    	if(instruction == 11){
    		gunMode = 0;
    	}
    	if(instruction == 12){
    		gunMode = 1;
    	}
    	if(instruction == 13){
    		gunMode = 2;
    	}
    	if(instruction == 14){
    		hasRifle = true;
    		GUI.add(createButton(rifleBMP, (fireBMP.getWidth() / 2) + pistolBMP.getWidth() + rifleBMP.getWidth(), height - 35, 12));
    	}
    	if(instruction == 15){
    		hasTNT = true;
    		GUI.add(createButton(tntBMP, (fireBMP.getWidth() / 2) + pistolBMP.getWidth() + rifleBMP.getWidth() + tntBMP.getWidth(), height - 35, 13));
    	}
    	if(instruction == 16){
    		unpause();
    	}
    	if(instruction == 17){
    		neworload();
    	}
    	if(instruction == 18){
    		resumeGame();
    	}
    	if(instruction == 19){
    		saver.save();
    	}
    	if(instruction == 20){
    		if(GameView.hasRifle){
        		action(14);
        	}
        	if(GameView.hasTNT){
        		action(15);
        	}
        	
        	
        	GameView.playing = true;
    	}
    }
       
    public void spawn(){
    	if(score > monstersSpawned){
    		monstersSpawned++;
    		if(monstersSpawned % 2 == 0){
    			createHeal();
    		}
    		playerHolder.get(0).addMaxHealth(.1f);
    		if(hardcore){
    			if(monstersSpawned >= 150){
    				createBullet();
    			}
    			if(monstersSpawned >= 250){
    				createBullets(2);
    			}
    			if(monstersSpawned >= 500){
    				createBullet();
    			}
    			if(monstersSpawned >= 750){
    				createBullets(9);
    			}
    			if(monstersSpawned >= 1000){
    				createBullets(25);
    			}
    			if(monstersSpawned >= 1500){
    				createBullets(5);
    			}	
    		}
    		if(monstersSpawned >= 0){
    			Skeli skeli = createSkeli(random.nextInt(xBound - 5), random.nextInt(yBound - 5));
    			enameys.add(skeli);
    		}
    		if(monstersSpawned == 150){
    			Rifle rifle = createRifle(R.drawable.rifle, random.nextInt(xBound - 5), random.nextInt(yBound - 5));
    			items.add(rifle);
    		}
    		if(monstersSpawned == 250){
    			Boss1 boss1 = createBoss1(random.nextInt(xBound - 5), random.nextInt(yBound - 5));
    			enameys.add(boss1);
    		}
    		if(monstersSpawned >= 250){
    			Spider spider = createSpider(random.nextInt(xBound - 5), random.nextInt(yBound - 5));
    			enameys.add(spider);
    		}
    		if(monstersSpawned == 450){
    			TNT tnt = createTNT(R.drawable.tnt, random.nextInt(xBound - 5), random.nextInt(yBound - 5));
    			items.add(tnt);
    		}
    		if(monstersSpawned == 500){
    			Boss2 boss2 = createBoss2(random.nextInt(xBound - 5), random.nextInt(yBound - 5));
    			enameys.add(boss2);
    		}
    		if(monstersSpawned >= 500 && monstersSpawned < 1250){
    			Bomber bomber = createBomber(random.nextInt(xBound - 5), random.nextInt(yBound - 5));
    			enameys.add(bomber);
    		}
    		if(monstersSpawned == 750){
    			Boss3 boss3 = createBoss3(random.nextInt(xBound - 5), random.nextInt(yBound - 5));
    			enameys.add(boss3);
    		}
    		if(monstersSpawned >= 750){
    			Multifyer multifyer = createMultifyer(random.nextInt(xBound - 5), random.nextInt(yBound - 5));
    			enameys.add(multifyer);
    		}
    		if(monstersSpawned == 1000){
    			Boss4 boss4 = createBoss4(random.nextInt(xBound - 5), random.nextInt(yBound - 5));
    			enameys.add(boss4);
    		}
    		if(monstersSpawned >= 1000){
    			Raper raper = createRaper(random.nextInt(xBound - 5), random.nextInt(yBound - 5));
    			enameys.add(raper);
    		}
    		if(monstersSpawned == 1250){
    			Boss5 boss5 = createBoss5(random.nextInt(xBound - 5), random.nextInt(yBound - 5));
    			enameys.add(boss5);
    		}
    		if(monstersSpawned == 1500){
    			FinalBoss finalboss = createFinalBoss(random.nextInt(xBound - 5), random.nextInt(yBound - 5));
    			enameys.add(finalboss);
    		}
    	}
    }
    
    public void scroll(){
    	if(xScroll <= xBound - width){
    		if(playerHolder.get(0).x - xScroll >= (width * .5) && playerHolder.get(0).speed > 0){
    			xScroll += playerHolder.get(0).xSpeed;
    		}
    	}
    	   
    	if(yScroll <= yBound - height){
    		if(playerHolder.get(0).y - yScroll >= (height * .5) && playerHolder.get(0).ySpeed > 0){
    			yScroll += playerHolder.get(0).ySpeed;
    		}
    	}
    	   
    	if(xScroll > 0){
    		if(playerHolder.get(0).x - xScroll <= (width * .35) && playerHolder.get(0).xSpeed < 0){
    			xScroll += playerHolder.get(0).xSpeed;
    		}
    	}
    	   
    	if(yScroll > 0){
    		if(playerHolder.get(0).y - yScroll <=(height * .45) && playerHolder.get(0).ySpeed < 0){
    			yScroll += playerHolder.get(0).ySpeed;
    		}
    	}
    	if(xScroll < 0){
    		xScroll = 0;
    	}
    	if(yScroll < 0){
    		yScroll = 0;
    	}
    }
 
    @SuppressWarnings("unused")
    private Sprite createSprite(int resouce, int rows, int columns, int x, int y) {
    	Bitmap bmp = BitmapFactory.decodeResource(getResources(), resouce);
    	return new Sprite(this, bmp, rows, columns);
    }
       
    private Button createButton(Bitmap bmp, int x, int y) {
    	return new Button(bmp, x, y);
    }
       
    private Button createButton(Bitmap bmp, int x, int y, int instruction) {
    	return new Button(bmp, x, y, instruction);
    }
       
    private Skeli createSkeli(int x, int y) {
    	return new Skeli(this, skeliBMP, x, y);
    }
    protected Skeli createSkeli(int x, int y, int life) {
    	return new Skeli(this, skeliBMP, x, y, life);
    }
       
    private Spider createSpider(int x, int y) {
    	return new Spider(this, spiderBMP, x, y);
    }
    protected Spider createSpider(int x, int y, int life) {
    	return new Spider(this, spiderBMP, x, y, life);
    }
    
    private Bomber createBomber(int x, int y) {
    	return new Bomber(this, bomberBMP, x, y);
    }
    protected Bomber createBomber(int x, int y, int life) {
    	return new Bomber(this, bomberBMP, x, y, life);
    }
    
    private Multifyer createMultifyer(int x, int y) {
    	return new Multifyer(this, multifyerBMP, x, y);
    }
    
    protected Multifyer createMultifyer(int x, int y, float life) {
    	return new Multifyer(this, multifyerBMP, x, y, life);
    }
    
    private Raper createRaper(int x, int y) {
    	return new Raper(this, raperBMP, x, y);
    }
    protected Raper createRaper(int x, int y, int life) {
    	return new Raper(this, raperBMP, x, y, life);
    }
    
    private Boss1 createBoss1(int x, int y) {
    	return new Boss1(this, boss1BMP, x, y);
    }
    protected Boss1 createBoss1(int x, int y, int life) {
    	return new Boss1(this, boss1BMP, x, y, life);
    }
    
    private Boss2 createBoss2(int x, int y) {
    	return new Boss2(this, boss2BMP, x, y);
    }
    protected Boss2 createBoss2(int x, int y, int life) {
    	return new Boss2(this, boss2BMP, x, y, life);
    }
    
    private Boss3 createBoss3(int x, int y) {
    	return new Boss3(this, boss3BMP, x, y);
    }
    protected Boss3 createBoss3(int x, int y, int life) {
    	return new Boss3(this, boss3BMP, x, y, life);
    }
    
    private Boss4 createBoss4(int x, int y) {
    	return new Boss4(this, boss4BMP, x, y);
    }
    protected Boss4 createBoss4(int x, int y, int life) {
    	return new Boss4(this, boss4BMP, x, y, life);
    }
    
    private Boss5 createBoss5(int x, int y) {
    	return new Boss5(this, boss5BMP, x, y);
    }
    
    private FinalBoss createFinalBoss(int x, int y) {
    	return new FinalBoss(this, finalBossBMP, x, y);
    }
    protected FinalBoss createFinalBoss(int x, int y, int life) {
    	return new FinalBoss(this, finalBossBMP, x, y, life);
    }
    
    protected Boss5 createBoss5(int x, int y, int life) {
    	return new Boss5(this, boss5BMP, x, y, life);
    }
    
    private TrackerBall createBall(int resouce, int x, int y, int ID) {
    	Bitmap bmp = BitmapFactory.decodeResource(getResources(), resouce);
    	return new TrackerBall(this, bmp, x, y, ID);
    }
    protected TrackerBall createBall(int resouce, int x, int y, int ID, int life) {
    	Bitmap bmp = BitmapFactory.decodeResource(getResources(), resouce);
    	return new TrackerBall(this, bmp, x, y, ID, life);
    }
       
    protected Rifle createRifle(int resouce, int x, int y) {
    	Bitmap bmp = BitmapFactory.decodeResource(getResources(), resouce);
    	return new Rifle(this, bmp, x, y);
    }
    
    protected TNT createTNT(int resouce, int x, int y) {
    	Bitmap bmp = BitmapFactory.decodeResource(getResources(), resouce);
    	return new TNT(this, bmp, x, y);
    }
    
    private static void bossIsDead(){
    	isbossDead = true;
    }
       
    public void bulletCollsion(List<Bullet> bullet, List<Entity> enamy){
    	for (int o = 0; o < bullet.size(); o++){
    		for (int i = 0; i < enamy.size(); i++){
    			if(bullet.get(o).life > 0 && bullet.get(o).getMe().intersect(enamy.get(i).getMe())){
    				bullet.get(o).life -= enamy.get(i).bulletdam;
    				enamy.get(i).hit();
    				
    				if(enamy.get(i).life < 1){
    					if(enameys.get(i).ObjectID == ObjectIDs.bomeber){
        					createExplosion((int) enameys.get(i).x, (int) enameys.get(i).y);
        				}
    					if(enameys.get(i).ObjectID == ObjectIDs.finalboss){
        					bossIsDead();
        				}
    					if(bossBattle){
    						createCoin();
    					}
    					if(enamy.get(i).ObjectID == ObjectIDs.finalboss){
    						bossBattle = false;
    						bossIsDead();
    					}
    					enamy.remove(i);
    				}else{
    					if(enamy.get(i).ObjectID == ObjectIDs.multifyer){
    						enameys.add(createMultifyer((int) (enamy.get(i).x - 30), (int) (enamy.get(i).x - 50), enamy.get(i).life));
    						enameys.add(createMultifyer((int) (enamy.get(i).x + 30), (int) (enamy.get(i).x + 50), enamy.get(i).life));
    					}
    				}
    				if(bullet.get(o).life < 1){
    					if(o != 0){
    						o--;
    					}
    					i = 0;
    					bullet.remove(o);
    				}else{
    					i--;
    				}
    				if(bullet.size() < 1){
    					break;
    				}
    			}
    		}
    	}
    }
       
    public void enamyCollision(Player player, List<Entity> enamys, List<Entity> items){
    	for (int i2 = 0; i2 < enamys.size(); i2++){
    		if(enamys.get(i2).getMe().intersect(player.getMe())){
    			player.hert(enamys.get(i2).dam);
    			if(enamys.get(i2).ObjectID == ObjectIDs.shadowball || enamys.get(i2).ObjectID == ObjectIDs.electricball || enamys.get(i2).ObjectID == ObjectIDs.fireball){
    				enamys.remove(i2);
    				if(i2 != 0){
    					i2--;
    				}else if(enamys.size() < 1){
    					i2++;
    				}else{
    					break;
    				}
    			}
    			if(enameys.get(i2).ObjectID == ObjectIDs.bomeber){
					createExplosion((int) enameys.get(i2).x, (int) enameys.get(i2).y);
					enamys.remove(i2);
    				if(i2 != 0){
    					i2--;
    				}else if(enamys.size() < 1){
    					i2++;
    				}else{
    					break;
    				}
				}
    		}
    		if(enameys.size() == 0){
    			break;
    		}
    		
    		for(int i = 0; i < items.size(); i++){
    			if(enameys.size() == 0){
        			break;
        		}if(items.size() == 0){
        			break;
        		}
    			if(enamys.get(i2).getMe().intersect(items.get(i).getMe()) && items.get(i).ObjectID == ObjectIDs.heath){
    				items.remove(i);
    				
    				if(i != 0){
    					i--;
    				}else if(enamys.size() < 1){
    					i++;
    				}else{
    					break;
    				}
    			}
    			if(enamys.get(i2).getMe().intersect(items.get(i).getMe()) && items.get(i).ObjectID == ObjectIDs.explsion && enamys.get(i2).ObjectID != ObjectIDs.bomeber){
    				enamys.remove(i2);
    				if(i2 != 0){
    					i2--;
    				}else if(enamys.size() < 1){
    					i2++;
    				}else{
    					break;
    				}
    			}
    		}
    	}
    	for (int i = 0; i < items.size(); i++){
    		if(items.get(i).getMe().intersect(player.getMe())){
    			if(items.get(i).ObjectID == ObjectIDs.rifle){
    				action(14);
    				items.remove(i);
    			}else if(items.get(i).ObjectID == ObjectIDs.tnt){
    				action(15);
    				items.remove(i);
    			}else if(items.get(i).ObjectID == ObjectIDs.heath){
    				playerHolder.get(0).heal();
    				items.remove(i);
    			}else if(items.get(i).ObjectID == ObjectIDs.bullet){
    				playerHolder.get(0).ammo += 1;
    				items.remove(i);
    			}
    		}
    	}
    }
       
//////////////////////////////////slopy update method///////////////////////////////////////////////////////////////////
    @Override
    protected void onDraw(Canvas canvas) {
    	for(int w = 0; w - grass.getWidth() < xBound; w += grass.getWidth()){
    		for(int h = 0; h - grass.getHeight() < yBound; h += grass.getHeight()){
    			canvas.drawBitmap(grass, w - xScroll, h - yScroll, null);
    		}
    	}
    	
    	if(loading){
    		if(System.currentTimeMillis() >= loadtime){
    			loaded = true;
        		loading = false;
    		}
    		canvas.drawText("" + (loadtime - System.currentTimeMillis()) / 1000, ((int) (width * .47)), ((int) (height * .47)), highscorePaint);
    	}
    	
    	if(loaded){
    		loaded = false;
    		action(20);
    	}
    		
    	if(playing){
    		
    		update();
    		   
    		Rect heath = new Rect((int) (110 - (playerHolder.get(0).life / (playerHolder.get(0).maxHealth /100))), 5, 110, 60);
    		canvas.drawRect(heath, healthPaint);
    		
    		for (int i = 0; i < coins.size(); i++) {
    				coins.get(i).onDraw(canvas);
    		}
    		   
    		canvas.drawText("Score: " + score, 115, 22, textPaint);
    		if(seconds < 10){
    			canvas.drawText("Time: " + minutes + ":0" + seconds, 115, 40, textPaint);
    		}else{
    			canvas.drawText("Time: " + minutes + ":" + seconds, 115, 40, textPaint);
    		}
    		if(hardcore){
    			canvas.drawText("Ammo: " + playerHolder.get(0).ammo, 115, 56, textPaint);
    		}
    		
    		for (int i = 0; i < items.size(); i++) {
    			if(items.get(i).checkSelf()){
    				items.remove(i);
    				if(i != 0){
    					i--;
    				}else if(items.size() < 1){
    					i++;
    				}else{
    					break;
    				}
    			}
    			if(items.size() > 0){
    				items.get(i).onDraw(canvas);
    			}
    		}
    		   
    		for (int i = 0; i < bullets.size(); i++){
    			bullets.get(i).move();
    			bullets.get(i).onDraw(canvas);
    			if(bullets.get(i).checkSelf()){
    				bullets.remove(i);
    			}
    		}
    		for (int i = 0; i < enameys.size(); i++){
    			enameys.get(i).onDraw(canvas);
    			if(enameys.get(i).ObjectID == ObjectIDs.boss1 || enameys.get(i).ObjectID == ObjectIDs.boss3){
    				
    			}else{
    				enameys.get(i).follow(playerHolder.get(0).getCenterX(), playerHolder.get(0).getCenterY());
    			}
    				
    			if(enameys.get(i).checkSelf()){
    				if(enameys.get(i).ObjectID == ObjectIDs.bomeber){
    					createExplosion((int) enameys.get(i).x, (int) enameys.get(i).y);
    				}
    				if(enameys.get(i).ObjectID == ObjectIDs.finalboss){
    					bossIsDead();
    				}
    				if(enameys.get(i).ObjectID == ObjectIDs.finalboss){
						bossBattle = false;
						bossIsDead();
					}
    				enameys.remove(i);
    				break;
    			}
    			
    			if(enameys.get(i).ObjectID == ObjectIDs.raper && (System.currentTimeMillis() / 1000) % 7 == 0 && enameys.get(i).command == 0){
    				enameys.add(createBall(R.drawable.shadow_ball, (int) enameys.get(i).x, (int) enameys.get(i).y, ObjectIDs.shadowball));
    				enameys.get(i).command = 1;
    			}else if(enameys.get(i).ObjectID == ObjectIDs.raper && enameys.get(i).command != 0 && (System.currentTimeMillis() / 1000) % 7 != 0){
    				enameys.get(i).command = 0;
    			}
    			
    			if(enameys.get(i).ObjectID == ObjectIDs.boss1 && (System.currentTimeMillis() / 1000) % 5 == 0 && enameys.get(i).command == 0){
    				enameys.add(createBall(R.drawable.fire_ball, (int) enameys.get(i).x, (int) enameys.get(i).y, ObjectIDs.fireball));
    				enameys.get(i).command = 1;
    			}else if(enameys.get(i).ObjectID == ObjectIDs.boss1 && enameys.get(i).command != 0 && (System.currentTimeMillis() / 1000) % 5 != 0){
    				enameys.get(i).command = 0;
    			}
    			
    			if(enameys.get(i).ObjectID == ObjectIDs.boss4 && (System.currentTimeMillis() / 1000) % 7 == 0 && enameys.get(i).command == 0){
    				enameys.add(createBall(R.drawable.fire_ball, (int) enameys.get(i).x, (int) enameys.get(i).y, ObjectIDs.fireball));
    				enameys.get(i).command = 1;
    			}else if(enameys.get(i).ObjectID == ObjectIDs.boss4 && enameys.get(i).command != 0 && (System.currentTimeMillis() / 1000) % 7 != 0){
    				enameys.get(i).command = 0;
    			}
    			
    			if(enameys.get(i).ObjectID == ObjectIDs.boss4 && (System.currentTimeMillis() / 1000) % 5 == 0 && enameys.get(i).command < 2){
    				enameys.add(createBall(R.drawable.lightning_ball, (int) enameys.get(i).x, (int) enameys.get(i).y, ObjectIDs.electricball));
    				enameys.get(i).command++;
    			}else if(enameys.get(i).ObjectID == ObjectIDs.boss4 && enameys.get(i).command != 0 && (System.currentTimeMillis() / 1000) % 5 != 0){
    				enameys.get(i).command = 0;
    			}
    			
    			if(enameys.get(i).ObjectID == ObjectIDs.boss3 && (System.currentTimeMillis() / 1000) % 8 == 0){
    				enameys.add(createSkeli((int) enameys.get(i).x, (int) enameys.get(i).y));
    			}else if(enameys.get(i).ObjectID == ObjectIDs.boss3 && (System.currentTimeMillis() / 1000) % 17 == 0){
    				enameys.add(createSpider((int) enameys.get(i).x, (int) enameys.get(i).y));
    			}else if(enameys.get(i).ObjectID == ObjectIDs.boss3 && (System.currentTimeMillis() / 1000) % 28   == 0){
    				enameys.add(createRaper((int) enameys.get(i).x, (int) enameys.get(i).y));
    			}
    			
    			if(enameys.get(i).ObjectID == ObjectIDs.boss5 && (System.currentTimeMillis() / 1000) % 5 == 0){
    				enameys.add(createSpider((int) enameys.get(i).x, (int) enameys.get(i).y));
    			}
    			if(enameys.get(i).ObjectID == ObjectIDs.boss5 && (System.currentTimeMillis() / 1000) % 11 == 0){
    				enameys.add(createMultifyer((int) enameys.get(i).x, (int) enameys.get(i).y));
    			}
    			if(enameys.get(i).ObjectID == ObjectIDs.boss5 && (System.currentTimeMillis() / 1000) % 19 == 0){
    				enameys.add(createRaper((int) enameys.get(i).x, (int) enameys.get(i).y));
    			}
    			if(enameys.get(i).ObjectID == ObjectIDs.boss5 && (System.currentTimeMillis() / 1000) % 36 == 0 && enameys.get(i).command < 1){
    				enameys.add(createBoss1((int) enameys.get(i).x, (int) enameys.get(i).y));
    				enameys.get(i).command = 1;
    				if((System.currentTimeMillis() / 1000) % 72 == 0 && crazy){
    					enameys.add(createBoss3(random.nextInt(xBound - 5), random.nextInt(xBound - 5)));
    				}
    				if(!crazy){
    					crazy = true;
    				}else if(crazy){
    					crazy = false;
    				}
    				
    			}else if(enameys.get(i).ObjectID == ObjectIDs.boss5 && (System.currentTimeMillis() / 1000) % 36 != 0 && enameys.get(i).command != 0){
    				enameys.get(i).command = 0;
    			}
    			
    			
    			
    			if(enameys.get(i).ObjectID == ObjectIDs.finalboss && (System.currentTimeMillis() / 1000) % 5 == 0){
    				int ballNum = random.nextInt(3);
    				if(ballNum == 0){
    					enameys.add(createBall(R.drawable.lightning_ball, (int) enameys.get(i).x, (int) enameys.get(i).y, ObjectIDs.electricball));
    				}else if(ballNum == 1){
    					enameys.add(createBall(R.drawable.fire_ball, (int) enameys.get(i).x, (int) enameys.get(i).y, ObjectIDs.fireball));
    				}else if(ballNum == 2){
    					enameys.add(createBall(R.drawable.shadow_ball, (int) enameys.get(i).x, (int) enameys.get(i).y, ObjectIDs.shadowball));
    				}else{
    					enameys.add(createBall(R.drawable.shadow_ball, (int) enameys.get(i).x, (int) enameys.get(i).y, ObjectIDs.shadowball));
    				}
    			}
    			if(enameys.get(i).ObjectID == ObjectIDs.finalboss && (System.currentTimeMillis() / 1000) % 30 == 0 && enameys.get(i).command < 1){
    				enameys.add(createBoss3(random.nextInt(xBound - 5), random.nextInt(yBound - 5)));
    				enameys.get(i).command = 1;
    				if(!crazy){
    					crazy = true;
    				}
    				if((System.currentTimeMillis() / 1000) % 60 == 0 && crazy){
    					enameys.add(createBoss5(random.nextInt(xBound - 5), random.nextInt(xBound - 5)));
    					crazy = false;
    				}
    			}else if(enameys.get(i).ObjectID == ObjectIDs.finalboss && (System.currentTimeMillis() / 1000) % 30 != 0 && enameys.get(i).command != 0){
    				enameys.get(i).command = 0;
    			}
/*69*/    		}
        	   
    		playerHolder.get(0).onDraw(canvas);
        	   
    		bulletCollsion(bullets, enameys);
        	   
    		if(playerHolder.get(0).life < 1){
    			playing = false;
    			end();
    		}
    		if(minutes <= 0 && seconds <= 0){
    			end();
    		}
    	}
    	   
    	for (int i = 0; i < GUI.size(); i++) {
    		GUI.get(i).onDraw(canvas);
    	}
    	if(displayScores){
    		canvas.drawText("easy    : " + bundle.get(0).getInt("easy_highscore", 0), (int) (width * .25), (int) (height * .20), highscorePaint);
    		canvas.drawText("normal: " + bundle.get(0).getInt("normal_highscore", 0), (int) (width * .25), (int) (height * .40), highscorePaint);
    		canvas.drawText("hard    : " + bundle.get(0).getInt("hard_highscore", 0), (int) (width * .25), (int) (height * .60), highscorePaint);
    		canvas.drawText("harder : " + bundle.get(0).getInt("hardcore_highscore", 0), (int) (width * .25), (int) (height * .80), highscorePaint);
    	}
    }
       
    public void update(){
    	long timeLeft = 0;
    	
    	if(hardcore){
    		timeLeft = (2700000 - (System.currentTimeMillis() - beginTime)) / 1000;
    	}else if(gameDif == 1){
    		timeLeft = (3600000 - (System.currentTimeMillis() - beginTime)) / 1000;
    	}else if(gameDif == 2){
    		timeLeft = (3300000 - (System.currentTimeMillis() - beginTime)) / 1000;
    	}else if(gameDif == 3){
    		timeLeft = (3000000 - (System.currentTimeMillis() - beginTime)) / 1000;
    	}
    	   
    	minutes = (int) (timeLeft / 60);
    	seconds = (int) (timeLeft % 60);
    	   
    	if(score <= 1000 && coins.size() < 500){
    		createCoin();
    	}else if(isbossDead && coins.size() < 500){
    		createCoin();
    	}
    	   
    	if(move){
    		gameTouch((xTouch + xScroll), (yTouch + yScroll));
    		playerHolder.get(0).coinCollision(coins);
    		scroll();
    		
    	}else {
    		playerHolder.get(0).xSpeed = 0;
    		playerHolder.get(0).ySpeed = 0;
    	}
    	   
    	if(hardcore && playerHolder.get(0).ammo > 0 && shootPressed != 0 && gunMode == 1 && System.currentTimeMillis() - lastRifleShoot >= 333){
    		shootBullet(R.drawable.bullet, (int) playerHolder.get(0).x, (int) playerHolder.get(0).y);
    		playerHolder.get(0).ammo--;
    		lastRifleShoot = System.currentTimeMillis();
    	}else if(!hardcore && shootPressed != 0 && gunMode == 1 && System.currentTimeMillis() - lastRifleShoot >= 333){
    		shootBullet(R.drawable.bullet, (int) playerHolder.get(0).x, (int) playerHolder.get(0).y);
    		lastRifleShoot = System.currentTimeMillis();
    	}
    	   
    	enamyCollision(playerHolder.get(0), enameys, items);
    	   
    	spawn();
    }
       
    @Override
    public boolean onTouchEvent(MotionEvent event) {
    	/*if(event.getAction() == MotionEvent.ACTION_DOWN){
    		isPressed = true;
    	}else if(event.getAction() == MotionEvent.ACTION_UP){
    		isPressed = false;
    	}*/
    	
    	switch(event.getAction() & MotionEvent.ACTION_MASK) {

        case MotionEvent.ACTION_DOWN:
            //first finger went down
        	for (int i = GUI.size() - 1; i >= 0; i--) {
				Button button = GUI.get(i);
				if (button.isCollition(event.getX(0), event.getY(0))) {
					if(GUI.get(i).getAction() != 8 || shootPressed == 0){
						if(GUI.get(i).getAction() == 8){
							shootPressed = 1;
						}
						action(button.getAction());
					}
					buttonPressed = true;
					break;
				}
			}
        	if(!buttonPressed){
        		move = true;
        		xTouch = event.getX(0);
        		yTouch = event.getY(0);
        	}
        	
            break;

        case MotionEvent.ACTION_MOVE:
            //a touch placement has changed
        	if(buttonPressed){
        		
        	}else{
        		move = true;
        		xTouch = event.getX(0);
        		yTouch = event.getY(0);
        	}
            break;

        case MotionEvent.ACTION_UP:
            //first finger went up
        	if(buttonPressed){
        		buttonPressed = false;
        	}else {
        		move = false;
        	}
        	if(shootPressed != 0){
        		shootPressed = 0;
        	}
            break;

        case MotionEvent.ACTION_CANCEL:
            //gesture aborted (I think this means the finger was dragged outside of the touchscreen)
            break;

        case MotionEvent.ACTION_POINTER_DOWN:
            //second finger (or third, or more) went down.]
        	for (int i = GUI.size() - 1; i >= 0; i--) {
				Button button = GUI.get(i);
				if (button.isCollition(event.getX(1), event.getY(1) )) {
					if(GUI.get(i).getAction() != 8 || shootPressed == 0){
						if(GUI.get(i).getAction() == 8){
							shootPressed = 2;
						}
						action(button.getAction());
					}
					
					buttonPressed2 = true;
					break;
				}
			}
            break;

        case MotionEvent.ACTION_POINTER_UP:
            //second finger (or more) went up.
        	if(buttonPressed2){
        		 buttonPressed2 = false;
        	}
        	
        	if(shootPressed == 2){
        		shootPressed = 0;
        	}
        	
        	if(buttonPressed){
        		buttonPressed = false;
        	}
        	move = false;
        	for (int i = GUI.size() - 1; i >= 0; i--) {
				Button button = GUI.get(i);
				if (button.isCollition(event.getX(0), event.getY(0))) {
					if(GUI.get(i).getAction() != 8 || shootPressed == 0){
						if(GUI.get(i).getAction() == 8){
							shootPressed = 1;
						}
						action(button.getAction());
					}
					buttonPressed = true;
					
					break;
				}
			}
        	
        	if(!buttonPressed){
        		move = true;
        		xTouch = event.getX(0);
        		yTouch = event.getY(0);
        	}
        	
            break;
       

            default: break;
        }
    	return true;
    }
       
    public void gameTouch(float x, float y){
    	playerHolder.get(0).follow(x, y);
    }
}